const fs = require('fs')
const path = require('path')
let data = fs.readFileSync(path.resolve(__dirname, './demo1.pegjs'), 'utf-8')
const peggy = require('peggy')
const os = require('os')
const parser = peggy.generate(data)
let cssData = fs.readFileSync(path.resolve(__dirname, '../css_rpx.json'), { encoding: 'utf8', flag: 'r' })
// 这里的data是读取到的JSON内容
const cssMap = JSON.parse(cssData)
function ignoreDecl(decl) {
  // console.log('🚀 ~ file: index.js:29 ~ notConvert ~ cdcl:', decl)

  if (/overflow-wrap/.test(decl)) {
    return true
  }
  if (/font-family/.test(decl)) {
    return true
  }

  //删除flex-direction,是因为display:flex默认就是flex-direction:row
  if (/flex-direction:\s*row\s*/.test(decl)) {
    return true
  }
  if (/font-weight:\s*normal\s*/.test(decl)) {
    return true
  }
  return false
}

function notDeclConvert(cdcl) {
  if (/^\s*@/.test(cdcl)) {
    return true
  }
  if (/\/\//.test(cdcl)) {
    return true
  }
  if (/\/\*/.test(cdcl)) {
    return true
  }
  if (/\$/.test(cdcl)) {
    return true
  }
  // css变量
  if (/var\(/.test(cdcl)) {
    return true
  }
  return false
}
function notSelectorConvert(cdcl, parent = '') {
  let arr=cdcl.replace(/\s*$/,'').split(/\s+/)
  cdcl=arr[arr.length-1];
  if (/[:+~>#]/.test(cdcl)) {
    return true
  }
  if (/^\s*@/.test(cdcl)) {
    return true
  }
  if (/\/deep\//.test(cdcl)) {
    return true
  }
  if (!/^\./.test(cdcl)) {
    if (parent && /^&/.test(cdcl) && /^\./.test(parent)) {
      return false
    }
    return true
  }
  return false
}

function dealScss(scssArr, isTran, parent) {
  return scssArr.reduce((pre, cur) => {
    if (typeof cur == 'string') {
      pre += cur
      pre += os.EOL
      return pre
    }
    let selector = cur.selector
    let notConvert = notSelectorConvert(selector, parent)
    let rules = []
    let subTmp = ''
    let subRules = cur?.subRules ?? []
    subRules.forEach(decl => {
      if (/rgba\(/.test(decl)) {
        decl = convertRgbaToHex(decl)
      }
      if (typeof decl == 'string') {
        if (notConvert || !isTran) {
          subTmp += decl
          subTmp += os.EOL
        } else {
          let cdcl = decl
            .replace(/[\r\n]/g, '')
            .replace(/;.*$/g, '')
            .replace(/:\s/, ':')
          if (!cssMap[cdcl] && !ignoreDecl(cdcl)) {
            subTmp += decl.replace(/[\r\n]/g, '')
            subTmp += os.EOL
          }
        }
      } else {
        parent = /^&/.test(selector) ? parent : selector
        subTmp += dealScss([decl], !notConvert, parent)
      }
    })
    if (subTmp) {
      if (cur.selector) {
        pre += cur.selector + `{${os.EOL}`
      }
      pre += subTmp
      pre += `}${os.EOL}`
    }
    return pre
  }, '')
}
function rgbaToHex(string, realString) {
  var colors = string
    .replace('rgb', '')
    .replace('a', '')
    .replace('(', '')
    .replace(')')
    .split(',')
    .slice(0, 3)
    .map(function (v) {
      v = parseInt(v).toString(16)
      return v.length == 1 ? '0' + v : v
    })
  return '#' + colors.join('')
}
function convertRgbaToHex(fileContent) {
  fileContent = fileContent.replace(/(rgba)(\s*?)(\()(\s*?)([0-9]{1,3})(\s*?)(\,)(\s*?)([0-9]{1,3})(\s*?)(\,)(\s*?)([0-9]{1,3})(\s*?)(\,)(\s*?)(0?)(\.?)([0-9]*)(\s*?)(\))/g, (...para) => {
    if (para[19] != 0 && para[19] != 1) {
      return para[0]
    }

    // fileContent=fileContent.replace(/font-family:\s*.*;/g,"")
    // fileContent=fileContent.replace(/font-family:\s*.*;/g,"")
    return rgbaToHex(para[0])
  })
  return fileContent
}

function crudeScss(scssArr,parent="") {
  return scssArr.reduce((pre, cur) => {
    if (typeof cur == 'string') {
      return pre
    }
    if (/[@:]/.test(cur.selector)) {
      return pre;
    }
    let rules = []
    let subTmp = ''
    let subRules = cur?.subRules ?? []
    subRules.forEach(decl => {
      if (typeof decl == 'string') {
        if (/rgba\(/.test(decl)) {
          decl = convertRgbaToHex(decl)
        }
        if (!notDeclConvert(decl) && !ignoreDecl(decl)) {
          subTmp += decl.replace(/[\r\n]/g, '')
          subTmp += os.EOL
        }
      } else {
        rules.push(decl)
      }
    })
    subTmp += crudeScss(rules)
    if (subTmp) {
      if (cur.selector) {
        pre += cur.selector + `{${os.EOL}`
      }
      pre += subTmp
      pre += `}${os.EOL}`
    }
    return pre
  }, '')
}

function scssToCss(style) {
  let res = parser.parse(style)
  return dealScss(res, true, '')
}

function canRemoveRule(res, selector) {
  // console.log("🚀 ~ file: index.js:46 ~ canRemoveRule ~ selector:", selector);
  for (let i = 0; i < res.length; i++) {
    let obj = res[i]
    if (!obj?.selector) {
      continue
    }
    let cur = obj.selector.replace(/\s*$/, '')
    if (obj.selector.indexOf(',') >= 0) {
      return false
    }
    if (cur == '.' + selector) {
      return !obj?.subRules?.length
    }
    let can = canRemoveRule(obj?.subRules ?? [], selector)
    if (!can) {
      return false
    }
  }
  return true
}

function canRemove(style, selector) {
  let res = parser.parse(style)
  return canRemoveRule(res, selector)
}
async function trimScss(style) {
  let res = parser.parse(style)
  const prettier = require('prettier')
  const formattedScssCode = prettier.format(crudeScss(res,""), {
    parser: 'scss',
  })
  return formattedScssCode
}

module.exports = { scssToCss, canRemove, trimScss }
// !async function () {
//   let txt = fs.readFileSync(path.resolve(__dirname, './demo1.txt'), 'utf-8')
//   let dd = await trimScss(txt)
//   console.log('🚀 ~ file: index.js:74 ~ dd:', dd)
//   // let res = parser.parse(txt)
//   // let can = canRemove(txt, 'list-items_1-0')
//   // console.log(res)
// }()
